package com.myrpc.processor;

import com.myrpc.annotation.MyRpcRemote;
import com.myrpc.proxy.CglibProxyFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

@Slf4j
@Component
public class SpringBeanPostProcessor implements BeanPostProcessor {
    @Autowired
    CglibProxyFactory cglibProxyFactory;

    /**
     * Spring Bean 实例化之前调用本方法
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    /**
     * Spring Bean 实例化之后调用本方法
     * 将具有MyRpcRemote注解的成员更换成代理对象
     * @param bean bean
     * @param beanName bean name
     * @return bean
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> targetClass = bean.getClass();
        Field[] declaredFields = targetClass.getDeclaredFields();
        for (Field declaredField: declaredFields){
            MyRpcRemote myRpcRemote = declaredField.getAnnotation(MyRpcRemote.class);
            if (myRpcRemote != null){
                //存在MyRpcRemote注解; 生成代理对象
                Object proxy = cglibProxyFactory.getProxy(declaredField.getType());
                declaredField.setAccessible(true);
                try {
                    //使用代理对象来为原成员赋值
                    declaredField.set(bean, proxy);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
//        System.out.println("Bean:" + beanName);
        return bean;
    }
}
